#include "RoomManager.h"

SINGLETON_CLASS_INIT(CRoomManager);

bool CRoomManager::Init(s32 count)
{
    m_freeList.clear();
    m_usingList.clear();
    m_count = 0;
    m_flag = new s8[count];
    if( !m_flag )
    {
        return false;
    }

    m_count = count;
    memset( m_flag, E_Room_Free, sizeof(s8) * count );
    for( s32 i=0; i<m_count; ++i )
    {
        m_freeList.insert( i );
    }

    return true;
}

void CRoomManager::Fini()
{
    if( m_flag )
    {
        delete [] m_flag;
        m_flag = NULL;
    }
}

s32 CRoomManager::GetRoom()
{
    if( m_freeList.size() == 0 ) 
    {
        return INVALID_VAL;
    }

    std::set<s32>::iterator it = m_freeList.begin();
    s32 id = *it;

    _SetRoomFlag( id, E_Room_InUse );
    m_usingList.insert( id );
    m_freeList.erase( it );
    m_halfFullList.insert( id );

    LOG_INFO( "[%s][%s][%d] free[%d] using[%d] getid[%d]",
        __FILE__, __FUNCTION__, __LINE__, 
        m_freeList.size(), m_usingList.size(), id );

    return id;
}

s32 CRoomManager::GetRoom(s32 id)
{
    if( m_freeList.size() == 0 ) 
    {
        return INVALID_VAL;
    }
    s32 retid = INVALID_VAL;
    std::set<s32>::iterator it = m_freeList.find( id );
    if( it != m_freeList.end() )
    {
        retid = *it;

        _SetRoomFlag( id, E_Room_InUse );
        m_usingList.insert( id );
        m_freeList.erase( it );
        m_halfFullList.insert( id );
    }

    LOG_INFO( "[%s][%s][%d] free[%d] using[%d] trygetid[%d] retid[%d]",
        __FILE__, __FUNCTION__, __LINE__, 
        m_freeList.size(), m_usingList.size(), id, retid );

    return retid;
}

void CRoomManager::PutRoom(s32 id)
{
    /*
    if( RoomInUse(id) )
    {
        return;
    }
    */
    
    _SetRoomFlag( id, E_Room_Free );
    m_usingList.erase( id );
    m_freeList.insert( id );
    m_halfFullList.erase( id );
    
    LOG_INFO( "[%s][%s][%d] free[%d] using[%d] halffull[%d] putid[%d]",
        __FILE__, __FUNCTION__, __LINE__, 
        m_freeList.size(), m_usingList.size(), m_halfFullList.size(), id );
}

bool CRoomManager::RoomInUse(s32 id)
{
    if( id < 0 || id >= m_count )
    {
        return true;
    }

    return (m_flag[id] == E_Room_InUse);
}

const std::set<s32>& CRoomManager::GetUsingList()
{
    return m_usingList;
}

void CRoomManager::AddHalfFullRoom(s32 id)
{
    m_halfFullList.insert( id );
}

void CRoomManager::RemoveHalfFullRoom(s32 id)
{
    m_halfFullList.erase( id );
}

const std::set<s32>& CRoomManager::GetHalfFullList()
{
    return m_halfFullList;
}

void CRoomManager::_SetRoomFlag(s32 id, s8 flag)
{
    if( id < 0 || id >= m_count )
    {
        return;
    }

    m_flag[id] = flag;
}


